package channel;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

import datasource.ConnectionSSH;
import datasource.ConnectionSSH2;
/**
 * 管道方法类
 *
 *
 * @version 1.0
 * @since JDK1.7
 * @author yutao
 * @company 上海朝阳永续信息技术有限公司
 * @copyright (c) 2016 SunTime Co'Ltd Inc.All rights reserved.
 * @date 2017年4月28日下午3:49:46
 */
public class ChannelUtils {
	
	private Session session = null;
	private static Logger logger = LogManager.getLogger(ChannelUtils.class);
	
	/**
	 * exec 命令形式的管道方法
	 * @param cmd
	 * @return isError false有错误（result记录的就是错误信息），true没有错误（正常的结果）
	 * @author yutao
	 * @date 2017年4月28日下午3:49:59
	 */
	@Deprecated
	public Map<String, Object> commandExec(String cmd){
		
		List<String> result = new ArrayList<String>();
		
		this.session = ConnectionSSH2.dataSource.getSession();
//		this.session = ConnectionSSH.getSession();
		boolean flag = true;
		try {
			ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
			channelExec.setCommand(cmd);
			InputStream errStream = channelExec.getErrStream();
	        BufferedReader reader = new BufferedReader(new InputStreamReader(errStream));
	        BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));//从远程端到达的所有数据都能从这个流中读取到
//			channelExec.setOutputStream(System.out);//从远程端到达的所有数据消息（格式：SSH_MSG_CHANNEL_DATA）都将写入到该流中。
	        
			channelExec.connect();
			String msg;
			//获取错误信息
	        while((msg = reader.readLine()) != null){
	        	flag = false;
	        	result.add(msg);
//	        	logger.error(msg);
	        	while(true){
	        		if(channelExec.isClosed()){
			        	//状态0表示成功，-1表示如果命令尚未终止（或该通道类型没有命令），1，非执行成功推出，表示出现异常
		        		logger.error(msg + "--------exit-status: "+channelExec.getExitStatus());
		        		break;
		        	}
	        	}
	        }
			if(flag){
				while((msg = in.readLine()) != null){
					logger.debug("----execute----result-----" + msg);
					result.add(msg);
				}
			}
			in.close();
			channelExec.disconnect();
			
			
		} catch (JSchException e) {
			e.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("result", result);
		map.put("isError", flag);
		
		return map;
	}
	
	
	
	@Deprecated
	public List<String> commandExec3(String cmd){
		
		List<String> result = new ArrayList<String>();
		
//		this.session = ConnectionSSH2.dataSource.getSession();
		this.session = ConnectionSSH.getSession();
		try {
			ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
//			Channel channel =  session.openChannel("exec");
			
			channelExec.setCommand(cmd);
//			InputStream in = channelExec.getInputStream();
			
			InputStream errStream = channelExec.getErrStream();
	        
	        BufferedReader reader = new BufferedReader(new InputStreamReader(errStream));
	        BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
	        channelExec.connect();
			
			String msg = "";
//			while(true){
		        while((msg = reader.readLine()) != null){
		        	System.out.println(msg);
		        }
		        /*if(channelExec.isClosed()){
		        	//状态0表示成功，-1表示如果命令尚未终止（或该通道类型没有命令），1，非执行成功推出，表示出现异常
	        		System.out.println("exit-status: "+channelExec.getExitStatus());
//	        		break;
	        	}*/
//			}
		        
		        if(channelExec.isClosed()){
	        		  //状态0表示成功，-1表示如果命令尚未终止（或该通道类型没有命令），1
			          System.out.println("exit-status: "+channelExec.getExitStatus());
			    }    
		    
	        while((msg = in.readLine()) != null){
	        	result.add(msg);
	        }
			/*byte[] tmp = new byte[1024];
			while(true){
				while(in.available()>0){
					int i = in.read(tmp, 0, tmp.length);
					if(i < 0) break;
					result.add(new String(tmp, 0, i));
				}
				if(channelExec.isClosed()){
			          if(in.available()>0) continue;
			          System.out.println("exit-status: "+channelExec.getExitStatus());
			          break;
			    }
			}*/
			channelExec.disconnect();
		} catch (JSchException e) {
			e.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}
		return result;
	}



	/**
	 * 指定哪台服务器来执行命令
	 * @param cmd
	 * @param username
	 * @param serverip
	 * @param port
	 * @return
	 * @author yutao
	 * @date 2017年6月8日下午7:47:58
	 */
	public Map<String, Object> commandExec(String cmd, String username, String serverip, String port) {
		
		List<String> result = new ArrayList<String>();
		logger.debug("----拿session----commandExec----");
		this.session = ConnectionSSH2.dataSource.getSession(serverip, Integer.valueOf(port), username);
		boolean flag = true;
		try {
			ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
			channelExec.setCommand(cmd);
			InputStream errStream = channelExec.getErrStream();
	        InputStream inputStream = channelExec.getInputStream();
			channelExec.connect(1000);
			Thread.sleep(500L);
			//获取错误信息
			logger.debug("----开始读错误信息---start----available----" + errStream.available());
			byte[] buffer = new byte[1024];
			if(errStream.available() > 0){
				while(errStream.available() > 0){
					int i = errStream.read(buffer, 0, buffer.length);
					if(i < 0) break;
					String remoteStr = new String(buffer, 0, i);
					remoteStr = remoteStr.replaceAll("\r\n", "\n");
					String[] split = remoteStr.split("\n");
					for(String s:split){
						logger.debug("----远程返回的错误信息----" + s);
						result.add(s);
					}
					while(true){
		        		if(channelExec.isClosed()){
				        	//状态0表示成功，-1表示如果命令尚未终止（或该通道类型没有命令），1，非执行成功推出，表示出现异常
			        		logger.error("--------exit-status: "+channelExec.getExitStatus());
			        		break;
			        	}
		        	}
				}
			}
	        errStream.close();
			if(flag){
				while(inputStream.available() > 0){
					int i = inputStream.read(buffer, 0, buffer.length);
					if(i < 0) break;
					
					String remoteStr = new String(buffer, 0, i);
					result.add(remoteStr);
				}
				inputStream.close();
			}
			channelExec.disconnect();
		} catch (JSchException e) {
			logger.error("----commandExec----jsch----" + e.getStackTrace());
		}catch (IOException e){
			logger.error("----commandExec----IO----" + e.getStackTrace());
		} catch (Exception e) {
			logger.error("----commandExec----Thread.sleep----" + e.getStackTrace());
		}
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("result", result);
		map.put("isError", flag);
		
		return map;
	}
	

}
